/******************************************************************************
 *
 * Copyright:
 *    (C) 2000 - 2007 Embedded Artists AB
 *
 * Description:
 *    Main program for LPC2148 Education Board test program
 *
 *****************************************************************************/

#include "../pre_emptive_os/api/osapi.h"
#include "../pre_emptive_os/api/general.h"
#include <printf_P.h>
#include <ea_init.h>
#include <lpc2xxx.h>
#include <consol.h>

#include "pca9532.h"
#include "testLcd.h"
#include "eeprom.h"
#include "testMotor.h"
#include "testSound.h"
#include "testAccelerometer.h"
#include "lcd.h"
#include "testSD.h"


#define PROC1_STACK_SIZE 2048
#define PROC2_STACK_SIZE 2048
#define PROC3_STACK_SIZE 2048
#define PROC4_STACK_SIZE 2048
#define PROC5_STACK_SIZE 2048
#define PROC6_STACK_SIZE 2048
#define INIT_STACK_SIZE  400

static tU8 proc1Stack[PROC1_STACK_SIZE];
static tU8 proc2Stack[PROC2_STACK_SIZE];
static tU8 proc3Stack[PROC3_STACK_SIZE];
static tU8 proc4Stack[PROC4_STACK_SIZE];
static tU8 proc5Stack[PROC5_STACK_SIZE];

static tU8 initStack[INIT_STACK_SIZE];
static tU8 pid1;
static tU8 pid2;
static tU8 pid3;
static tU8 pid4;
static tU8 pid5;


static void proc1(void* arg);
static void proc2(void* arg);
static void proc3(void* arg);
static void proc4(void* arg);
static void proc5(void* arg);

static void initProc(void* arg);

volatile tU32 msClock = 0;
tU8 xbeePresent;


//motor variables
tS8 latestDirection = 1; // -1 for left, 1 for right(default)
tS8 latestStepPower = 1; // max is 3 , min is 0, 1 is default
tU32 motorPower;

tS16 temp = 0;
int depth = 0;
int boatTilt=0;

tS16* temp_ptr= &temp;
int* depth_ptr = &depth;
int* boatTilt_ptr = &boatTilt;

int main(void) {
	tU8 error;
	tU8 pid;

	//immediately turn off buzzer (if connected)
	IODIR0 |= 0x00000080;
	IOSET0 = 0x00000080;

	osInit();

	osCreateProcess(initProc, initStack, INIT_STACK_SIZE, &pid, 1, NULL, &error);
	osStartProcess(pid, &error);

	osStart();
	return 0;
}

static void initProc(void* arg) {
	tU8 error;

	eaInit();


	//RUN BUTTONS CHECKING PROCEDURE
	osCreateProcess(proc1, proc1Stack, PROC1_STACK_SIZE, &pid1, 3, NULL, &error);
	osStartProcess(pid1, &error);

	//RUN SD/MMC PROCEDURE
	osCreateProcess(proc2, proc2Stack, PROC2_STACK_SIZE, &pid2, 3, NULL, &error);
	osStartProcess(pid2, &error);

	//RUN MOTOR PROCEDURE
	osCreateProcess(proc3, proc3Stack, PROC3_STACK_SIZE, &pid3, 3, NULL, &error);
	osStartProcess(pid3, &error);

	//RUN LCD PROCEDURE
	osCreateProcess(proc4, proc4Stack, PROC4_STACK_SIZE, &pid4, 3, NULL, &error);
	osStartProcess(pid4, &error);

	//RUN LED's, ACCELEROMETER, TEMPERATURE, EXP LCD, SOUND PROCEDURE,
	osCreateProcess(proc5, proc5Stack, PROC5_STACK_SIZE, &pid5, 3, NULL, &error);
	osStartProcess(pid5, &error);



	osDeleteProcess();
}

static void proc1(void* arg) {

	while (1) {
		if ((IOPIN & 1 << 17) == 0) { // when joystick is pressed up
			printf("Pressed joystick to the UP \n");
			depth++;
			if (depth > 16) {
				depth = 16;
			}

		} else if ((IOPIN & 1 << 20) == 0) { // when joystick is pressed down
			printf("Pressed joystick to the DOWN \n");
			depth--;
			if (depth < 0) {
				depth = 0;
			}

		} else if ((IOPIN & (1 << 19)) == 0) { //when joystick is pressed to the left
			printf("Pressed joystick to the LEFT\n");
			latestDirection = -1;

		} else if ((IOPIN & (1 << 18)) == 0) { //when joystick is pressed to the right
			printf("Pressed joystick to the RIGHT\n");
			latestDirection = 1;

		}

		motorPower = readPotValue();

		osSleep(200);
	}
}

static void proc2(void* arg) {
	while(1){

		///osSleep(200);

		lcdInit();
		osSleep(10);
		lcdDisplayBoatTilt(3, boatTilt);

		osSleep(200);

		saveLog(temp_ptr,depth_ptr,boatTilt_ptr);
	}
}

static void proc3(void* arg) {
	initMotor();
	tS8 stepmotorIndex = 0;
	while(1) {
		if (motorPower < 1010) {
			stepmotorIndex = stepMotor(stepmotorIndex, latestDirection, motorPower);
		}
	}
}

static void proc4(void* arg) {


	initLCD();
	lcdBacklight(FALSE);

	while (1) {
		lcdPrint(temp, depth);
		osSleep(500);
	}
}

static void proc5(void* arg) {
	i2cInit();
	tU8 pca9532Present = pca9532Init();

	while (1) {
		//read current temperature
		temp = readTemperature();

		//display boat depth on the LED's
		runLeds(depth, pca9532Present);

		//read boat tilt
		boatTilt = testAccel();

		testSound();

		osSleep(200);
	}
}



void appTick(tU32 elapsedTime) {
	msClock += elapsedTime;
}
